Completed
Push — master ( 8caa6f...c37a57 )
by Jan
20s queued 13s
created

frames-builder.ts ➔ makeValueArray   A

Complexity

Conditions 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 3
1
import { convertWriteTagsToRawTags } from "./TagsConverters"
2
import { Frames } from "./frames/frames"
3
import { WriteTags } from "./types/Tags"
4
import { deduplicate, isBuffer, isKeyOf, isNotUndefinedEntry } from "./util"
5
import * as GenericFrames from './frames/generic'
6
import { getFrameOptions } from "./util-frame-options"
7
8
/**
9
 * Returns a buffer with the frames for the specified tags.
10
 */
11
export function buildFramesBuffer(tags?: WriteTags) {
12
    return Buffer.concat(buildFramesBuffers(tags))
13
}
14
15
/**
16
 * Returns an array of buffers using specified tags.
17
 */
18
function buildFramesBuffers(tags?: WriteTags): Buffer[] {
19
    if(!tags) {
20
        return []
21
    }
22
    const rawTags = convertWriteTagsToRawTags(tags)
23
    return Object.entries(rawTags)
24
        .filter(isNotUndefinedEntry)
25
        .map(([identifier, value]) => buildFrameBuffer(identifier, value))
26
        .filter(isBuffer)
27
}
28
29
function buildFrameBuffer(identifier: string, value: unknown) {
30
    if (isKeyOf(identifier, Frames)) {
31
        return handleMultipleAndBuildFrameBuffer(
32
            identifier,
33
            value,
34
            Frames[identifier].create
35
        )
36
    }
37
    if (identifier.startsWith('T')) {
38
        return GenericFrames.GENERIC_TEXT.create(identifier, value as string)
39
    }
40
    if (identifier.startsWith('W')) {
41
        return handleMultipleAndBuildFrameBuffer(
42
            identifier,
43
            value,
44
            url => GenericFrames.GENERIC_URL.create(identifier, url),
45
            deduplicate
46
        )
47
    }
48
    return null
49
}
50
51
function handleMultipleAndBuildFrameBuffer<
52
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
    Create extends (value: any, index: number) => Buffer | null
54
>(
55
    identifier: string,
56
    data: unknown,
57
    create: Create,
58
    deduplicate = (values: ([Parameters<Create>])[]) => values
59
) {
60
    const values = makeValueArray(identifier, data)
61
    const frames = deduplicate(values)
62
        .map(create)
63
        .filter(isBuffer)
64
    return frames.length ? Buffer.concat(frames) : null
65
}
66
67
/**
68
 * Throws if an array is given but not expected, i.e. the contract is not
69
 * respected, otherwise always return an array.
70
 */
71
function makeValueArray(identifier: string, data: unknown) {
72
    const isMultiple = getFrameOptions(identifier).multiple
73
    const isArray = Array.isArray(data)
74
    if (!isMultiple && isArray) {
75
        throw new TypeError(`Unexpected array for frame ${identifier}`)
76
    }
77
    return isMultiple && isArray ? data : [data]
78
}
79
80